<script lang="ts" setup>
import type { Dayjs } from 'dayjs';

import type { Recordable } from '@vben/types';

import type { DefApplicationModel, DefTenantApplicationRelModel } from '#/api';

import { onMounted, reactive } from 'vue';

import {
  Button,
  Card,
  DatePicker,
  Empty,
  Form,
  FormItem,
} from 'ant-design-vue';
import consola from 'consola';

import { DefApplicationApi } from '#/api';
import { PermCode } from '#/enums/perm';
import { dateUtil } from '#/utils/dateUtil';

import ApplicationTree from './resource-tree.vue';

interface Emits {
  (
    e: 'save',
    params: DefTenantApplicationRelModel.DefTenantApplicationRelSaveVO,
  ): void;
}

defineOptions({
  name: 'ApplicationTrees',
  inheritAttrs: false,
});

const emit = defineEmits<Emits>();
const permCode = PermCode.devOperation.application.defTenantApplicationRel;
interface State {
  applicationResourceList: DefApplicationModel.ApplicationResourceResultVO[];
  confirmLoading: boolean;
  appResMap: Record<string, string[]>;
  defaultExpandedNames: string[];
}
const formData = reactive<Recordable>({
  expirationTime: undefined,
  applicationResourceMap: {},
});

const state = reactive<State>({
  applicationResourceList:
    [] as DefApplicationModel.ApplicationResourceResultVO[],
  confirmLoading: false,
  appResMap: {},
  defaultExpandedNames: [],
});
const itemRefs: Record<string, any> = {};

const disabledDate = (current: Dayjs): boolean => {
  return current < dateUtil().endOf('day');
};

onMounted(async () => {
  state.applicationResourceList =
    await DefApplicationApi.findApplicationResourceList();
  state.defaultExpandedNames = state.applicationResourceList.map(
    (item) => item.defApplication.id as string,
  );
});

async function getData() {
  const appResourceMap: Record<string, string[]> = {};

  for (const item of state.applicationResourceList) {
    const itemRef = itemRefs[item.defApplication.id as string];
    if (!itemRef) {
      continue;
    }

    const checkedKeys = itemRef.treeRef.getCheckedKeys();
    const checkeds = itemRef.treeRef?.getCheckStrictly()
      ? (checkedKeys as any).checked
      : checkedKeys;

    if (itemRef.state.checkAll || itemRef.state.indeterminate) {
      appResourceMap[item.defApplication.id as string] = checkeds;
    }
    // 没有勾选应用的任何一条资源，视为该应用无需操作权限
    // else {
    //   appResourceMap[item.defApplication.id as string] = [];
    // }
  }
  formData.applicationResourceMap = appResourceMap;
  return formData;
}

async function load() {}

async function handleSubmit() {
  try {
    state.confirmLoading = true;
    const params = await getData();
    consola.log(params);
    emit('save', params);
  } finally {
    state.confirmLoading = false;
  }
}

defineExpose({ load });
</script>

<template>
  <Card title="企业授权" class="ml-1">
    <template #extra>
      <Button
        v-hasAnyPermission="[permCode.grant]"
        class="!ml-4"
        type="primary"
        :loading="state.confirmLoading"
        @click="handleSubmit"
      >
        {{ $t('common.saveText') }}
      </Button>
    </template>

    <Form class="p-4" :label-width="100" label-placement="left">
      <FormItem label="有效期">
        <DatePicker
          v-model:value="formData.expirationTime"
          format="YYYY-MM-DD HH:mm:ss"
          value-format="YYYY-MM-DD HH:mm:ss"
          placeholder="有效期"
          show-time
          :disabled-date="disabledDate"
        />
      </FormItem>
      <FormItem label="应用-资源">
        <ApplicationTree
          v-for="item in state.applicationResourceList"
          :key="item.defApplication.id"
          :ref="(el) => (itemRefs[item.defApplication.id as string] = el)"
          :application="item.defApplication"
          :resource-list="item.resourceList"
          :checked-keys="state.appResMap[item.defApplication.id as string]"
        />
        <Empty v-if="state.applicationResourceList.length === 0" />
      </FormItem>
    </Form>
  </Card>
</template>
